package tech.yixiyun.framework.kuafu.component;


import tech.yixiyun.framework.kuafu.component.register.*;
import tech.yixiyun.framework.kuafu.context.ApplicationContext;
import tech.yixiyun.framework.kuafu.kits.ClassKit;
import tech.yixiyun.framework.kuafu.log.LOGGER;

import java.util.ArrayList;
import java.util.List;

/**
 * 组件管理器，负责注册组件、注销组件。
 * 具体注册逻辑和注销逻辑，通过注册的ComponentRegistrar和ComponentUnregistrar实现
 */
public class ComponentRegistry {

    private static final List<IComponentRegistrar> registrars = new ArrayList<IComponentRegistrar>() {
        {
            //顺序不能乱，先生成BeanDefinition，
            add(new BeanComponentRegistrar());
            //再生成代理类，
            add(new EnhanceComponentRegistrar());
            //再去分析剩下的。
            add(new ControllerComponentRegistrar());
            add(new InterceptorComponentRegistrar());
            add(new ParamValueResolverComponentRegistrar());
            add(new BootedHandlerComponentRegistrar());
            add(new DomainComponentRegistrar());
            add(new DataSourceComponentRegistrar());
        }
    };




    /**
     * 添加新的组件注册器，新的组件注册器逻辑只会在内置注册器都执行完后才执行。<br/>
     * <b>WARN：</b>该方法不是线程安全的，请自行保证线程安全
     *
     * @param componentRegistrar
     */
    public static void addComponentRegistrar(IComponentRegistrar componentRegistrar) {
        registrars.add(componentRegistrar);
        LOGGER.info("组件注册器【" + componentRegistrar.getClass() + "】添加成功");
    }



    /**
     * 转发类给注册器
     *
     * @param className
     */
    public static void register(String className) {
        try {
            Class clazz = Class.forName(className, false, ApplicationContext.getServletContext().getClassLoader());

            register(clazz);
        } catch (Exception e) {
            if (e instanceof RuntimeException) {
                throw (RuntimeException) e;
            }
            throw new ComponentResolveException(e);
        }
    }


    /**
     * 转发类给注册器
     *
     * @param clazz
     */
    public static void register(Class clazz) {
        if (ClassKit.isBeanableClass(clazz) == false) {
            return;
        }
        for (IComponentRegistrar registrar : registrars) {
            registrar.register(clazz);
        }
    }





}
